package md5;

import com.alibaba.fastjson.JSON;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.nio.charset.Charset;
import java.nio.file.FileSystems;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class MD5SHATest {
    private static final Logger logger = LoggerFactory.getLogger(MD5SHATest.class);
    private static final Log log = LogFactory.getLog(MD5SHATest.class);
    private static MD5SHATest md5SHATest;
    private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

    private static void println(Object object) {
        System.out.println(object);
    }

    public static String toString(Object[] a) {
        if (a == null)


            return "null";
        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";

        StringBuilder b = new StringBuilder();
        b.append('[');
        for (int i = 0; ; i++) {
            b.append(a[i]);
            if (i == iMax)
                return b.append(']').toString();
            b.append(", ");
        }
    }

    @Test
    public void testSHA() throws Exception {

        String ss = "张海强";
        logger.info(ss);
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] bytes = messageDigest.digest(ss.getBytes());
            println(Arrays.toString(ss.getBytes()));
            println(Arrays.toString(bytes));
        } catch (NoSuchAlgorithmException e) {
            println(e.getMessage());
        }
//     println(Thread.currentThread().getName());
//     for(int i=0;;i++){
//         println("hahaha1");
//         if(i==5){
//             println("cycle");
//             break;
//         }
//         println("hahaha2");
//         Thread.sleep(5000);
//     }
        println(Integer.toHexString('马'));
        println((int) '张');
        println(Integer.toBinaryString('马'));

//1100110010010111

    }

    @Test
    public void fdfd() {
        byte bb = 034;
        Arrays.stream(new int[]{32, 434, 23});
        Stream.of();
        List<String> strings = new ArrayList<>(32);
        byte aaa = 0b1010101;
        byte bbb = 032;
        byte ccc = 0x12;
        byte[] bytes = {2, 3, 5, 35, 3};
        byte[] bytes1 = {'a', '2', '4'};
        int zhang = '张';
        println(zhang);
        System.out.printf("张海强是%s", "猪");
        int abc = 3;
        println(ddd(abc));
        println(abc);
        User user = new User("张海强", 28, "");
        changeUset(user);
        println(user.getAge());
        println(user.getName());


    }

    private int ddd(int ccc) {
        return ccc + 3;
    }

    private void changeUset(User user) {
        user.setAge(27);
        user.setName("张傻子");
        new User("", 2, "").hahaha();
    }

    @Test
    public void testAssert() {
        Assert.assertTrue(3 > 1);
        Assert.assertEquals(23, 23);
        Assert.assertEquals("这俩数不相等啊", 23, 23);
        Assert.assertNotNull("这个值是null啊", "");
    }

    @Before
    public void testBefore() {
        //println("nishizhume");
    }

    @Test
    public void testArray() {
        String[] strings = {"张", "海", "强"};
        Map<String, Object> map = new HashMap<>(32);
        println(Annotation.class.isAnnotation());
        Integer integer = 23;
        println(integer.getClass().isPrimitive());
        String[] strings1 = (String[]) Array.newInstance(String.class, 5);
        println(strings1.length);
        println(Arrays.toString(strings1));
        println(strings1[3]);
        long[] ints = new long[5];
        println(Arrays.toString(ints));

    }

    @Test
    public void testType() throws Exception {
        Field field = MD5SHATest.class.getDeclaredField("md5SHATest");
        Type type = field.getGenericType();
        println(type);
        Charset.availableCharsets();
        Charset.availableCharsets();
        println(Charset.availableCharsets().toString());
        println(FileSystems.getDefault().toString());

    }

    private <T extends Object> T get(T t) {
        return t;
    }

    @Test
    public void testSystem() {
        Map<String, String> map = System.getenv();
        for (Map.Entry entry : map.entrySet()) {
            // println(entry.getKey()+"..."+entry.getValue());
        }
        println(System.lineSeparator());
        System.getProperties();
        System.setProperty("jdbc.driver", "com.mysql.jdbc.driver");
        int count = 0;
        for (Map.Entry<Object, Object> entry : System.getProperties().entrySet()) {
            count++;
            // println(entry.getKey()+"..."+entry.getValue());
            if ("jdbc.driver".equalsIgnoreCase(entry.getKey().toString())) {
                println("找到了了" + "值为" + entry.getValue());
                break;
            }
            println(count);
        }
        println("我在第几行  " + count);

    }

    @Test
    public void testArrays() {
//        List<String> strings = Arrays.asList("1", "2", "3", "4");
//        Student student = new Student();
//        println(User.class.isInstance(student));
//        byte[] bytes = new byte[5];
//        println(Arrays.toString(bytes));
//        new Random().nextBytes(bytes);
//        println(Arrays.toString(bytes));
//        println(new Random().nextInt(5));
//        char fileSeparator = '\\';
//        println(fileSeparator);
//        char fileSeparater2 = '/';
//        println(fileSeparater2);
//        println('"');
//        String ss = "d:\\fdsf\\f";
//        System.getSecurityManager();

    }

    @Test
    public void testMessageDigest() throws NoSuchAlgorithmException, ClassNotFoundException {
        MessageDigest messageDigest = MessageDigest.getInstance("md5");
        byte[] bytes = "张海强是猪".getBytes();
        messageDigest.update(bytes);
        byte[] digest = messageDigest.digest();
        println(Arrays.toString(digest));
        println(Character.isDigit('3'));
        Map<String, Object> map = new HashMap<>(32);
        println(map.put(null, null));
        println(map.put("1", "1"));
        println(map.put("1", "2"));
        //map.put(null,"haha");
//        println(map.get("1"));
//        println(map.get("2"));
//        println(map.get("3"));
        Integer a = 2;
        Integer b = 2;
        println(a.equals(b));
        println(a == b);
        char c = '张';
        char d = '海';
        if (c == d) {
        }
        println((int) c);
        "".toCharArray();

        if (!("" instanceof String)) {
            println("fff");
        }
        char[] src = {'1', '2', '3', '4'};
        char[] des = new char[9];
        System.arraycopy(src, 0, des, 2, 5);
        println(Arrays.toString(src) + "...." + Arrays.toString(des));

    }

    @Test
    public void testStream() {
        String[] strings = {"ni", "shi", "zhu"};
        List<Integer> list = Arrays.stream(strings).map(String::length).collect(Collectors.toList());
        list.add(44);
        list.forEach(System.out::println);
        Map<String, Object> map = new HashMap<>(32);
        boolean b = list.stream().anyMatch(a -> a == 2);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
        LocalDateTime localDateTime = LocalDateTime.now();
        println(localDateTime);
        LocalDateTime localDateTime1 = LocalDateTime.of(2019, Month.APRIL, 23, 12, 34, 33, 34343433);
        println(localDateTime1);
        Duration duration;
        Period period = Period.of(3, 3, 2);
        // list.replaceAll();
        List<User> list1 = new ArrayList<>(32);
        list1.add(new User("张三", 22, ""));
        list1.add(new User("李四", 32, ""));
        list1.add(new User("王五", 45, ""));
        list1.add(new User("马流", 25, ""));
        list1.sort(Comparator.comparing(User::getAge));
        list1.forEach(System.out::println);
        User[] usersBefore = new User[4];
        User[] users = list1.toArray(usersBefore);

        println(Arrays.toString(users));
        println(Arrays.toString(usersBefore));
        println(users == usersBefore);
        println(users.equals(usersBefore));
        User user = new User("hahaha", 22, "");
        User user1 = new User("xixixi", 28, "");
        println(user.equals(user1));
        String sss = new String("haha");
        String ssss = "haha";
        println(sss.equals(ssss));
        println(sss.hashCode());
        println(ssss.hashCode());
        //  list1.removeIf();

        Boolean fff = Boolean.valueOf(true);
        Collections.addAll(list, 2, 24, 223, 32);

        new ArrayList<>(Arrays.asList(3, 3, 4));
        new HashMap<>(new HashMap<>());


    }

    @Test
    public void testNewDateTime() throws ParseException {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localDate = LocalDate.parse("2019-04-23", dateTimeFormatter);
        println(localDate);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = simpleDateFormat.parse("2019-12-12 12:12:12");
        println(date);

    }

    @Test
    public void testReduce() {
        int ccc = 0;

        int aaaa = Stream.of(1, 2, 3, 4, 5).reduce((sum, a) -> {
            println(sum);
            int tt = 3;
            println(tt + sum + ccc);
            sum += a;
            println(sum);

            return sum;

        }).orElse(9999);
        println(aaaa);

    }

    @Test
    public void testFlatMap() {
        List<String> lista = new ArrayList<>(32);
        List<String> listb = new ArrayList<>(32);


        Stream.of(lista, listb).map(Collection::iterator).sorted();
    }

    @Test
    public void name() {
    }

    @Test
    public void testRemoveIf() {
        Map<String, Object> map = new HashMap<>(32);
        map.put("1", "1");
        map.put("2", "2");
        map.put("3", "3");
        map.put("4", "");
        map.put("5", "");
        map.put("6", null);
        map.put("7", null);
        println(JSON.toJSONString(map));
        println(map);
        map.entrySet().removeIf(entry -> "1".equals(entry.getValue()));
        println(map);
        map.keySet().removeIf("2"::equals);
        println(map);
        println(map);
        println(Instant.now().toEpochMilli());
        println(Instant.now());


    }

    @Test
    public void testJoining() {
        //  Stream.of("zhangh","hai","qiang").collect(Collectors.toMap());
        Stream.of(new String[]{"1"});
        Arrays.stream(new String[]{"", "ff"});
        String[] strings = {};
        String[] strings1 = new String[0];
        String[] strings2 = new String[]{"1", "2", "3", "4"};
        List<String> list = Arrays.asList(strings2);
        String ssss = list.set(0, "www");
        println(list);
        println(ssss);
        println(Arrays.toString(strings2));

        println(Instant.now().toEpochMilli());
        println(Instant.now());

    }

    @Test
    public void testFutureTask() {
        FutureTask<String> futureTask1 = new FutureTask<>(() -> {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Thread.currentThread().getName();
        });
        FutureTask<String> futureTask2 = new FutureTask<>(() -> {
            try {
                Thread.sleep(15000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Thread.currentThread().getName();
        });
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        executorService.execute(futureTask1);
        executorService.execute(futureTask2);
        executorService.submit(futureTask1);
        Callable<String> callable1 = () -> {
            try {
                Thread.sleep(15000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Thread.currentThread().getName();
        };
        Callable<String> callable2 = () -> {
            try {
                Thread.sleep(15000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Thread.currentThread().getName();
        };
        List<Callable<String>> list = new ArrayList<>(32);
        list.add(callable1);
        list.add(callable2);
        println(Thread.currentThread().getName());
        try {
            executorService.invokeAll(list);
            executorService.invokeAny(list);
        } catch (InterruptedException | ExecutionException e) {
            println("发生中断异常和执行异常啦");
        }
        while (true) {
            try {
                if (futureTask1.isDone() && futureTask2.isDone()) {//  两个任务都完成
                    System.out.println("Done");
                    executorService.shutdown();
                    executorService.shutdownNow();
                    println("线程池已经关闭了");// 关闭线程池和服务
                    return;
                }

                if (!futureTask1.isDone()) { // 任务1没有完成，会等待，直到任务完成
                    println("任务一还没完成，需要进行等待");
                    System.out.println("FutureTask1 output=" + futureTask1.get());
                }

                System.out.println("Waiting for FutureTask2 to complete，只等待2秒");
                String s = futureTask2.get(2000L, TimeUnit.MILLISECONDS);
                if (s != null) {
                    System.out.println("FutureTask2 output=" + s);
                }
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                println("你超时了");
            }
        }

    }

    @Test
    public void testFuture() {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        Future<Integer> future = executorService.submit(() -> {
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 22;
        });

        try {
            println("我已经开启了一个异步任务去执行耗时计算，我可以愉快地去干其他事情了");
            Thread.sleep(5000);
            println("我已经做完我的事情了 ，现在要去获取异步任务的执行结果了");
            println(future.isDone());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        println(future.isDone());
        int result = 0;
        try {
            result = future.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        println(future.isDone());
        println("新启动的异步任务执行完成，执行结果为" + result);
        System.out.printf("hahaha%d%n", result);
        println("测试换行");

    }

    @Test
    public void testToMap() {
        Stream.of(new User("张三", 23, "1"), new User("李四", 25, "2")).collect(Collectors.toMap(User::getId, Function.identity()));
        List<User> users = Arrays.asList(new User("张三", 23, "1"), new User("李四", 25, "1"));
        // users.add(new User("王五",26,"3"));
        // users.remove(0);
    }

    @Test
    public void testStringFormat() {
        String str;
        str = String.format("Hi,%s", "王力");
        System.out.println(str);
        str = String.format("Hi,%s:%s.%s", "王南", "王力", "王张");
        System.out.println(str);
        System.out.printf("字母a的大写是：%c %n", 'A');
        System.out.printf("3>7的结果是：%b %n", 3 > 7);
        System.out.printf("100的一半是：%d %n", 100 / 2);
        System.out.printf("100的16进制数是：%x %n", 100);
        System.out.printf("100的8进制数是：%o %n", 100);
        System.out.printf("50元的书打8.5折扣是：%f 元%n", 50 * 0.85);
        System.out.printf("上面价格的16进制数是：%a %n", 50 * 0.85);
        System.out.printf("上面价格的指数表示：%e %n", 50 * 0.85);
        System.out.printf("上面价格的指数和浮点数结果的长度较短的是：%g %n", 50 * 0.85);
        System.out.printf("上面的折扣是%d%% %n", 85);
        System.out.printf("字母A的散列码是：%h %n", 'A');

        println("fsdf sdf df  f ".replaceAll("\\s+", ""));
        println((int) 'a');
    }

    @Test
    public void testJavaEE() {
    }

    @Test
    public void testBigDecimal() {
        BigDecimal bd = new BigDecimal("234.3");
        BigDecimal bigDecimal = BigDecimal.valueOf(1.3);
        println(bd.divide(bigDecimal, 2, RoundingMode.HALF_DOWN));
        System.out.println(new BigDecimal("123.45344436743635324274").setScale(3, RoundingMode.HALF_UP));
        System.out.println(new BigDecimal("125.656353214324", MathContext.DECIMAL32));

    }

    @Test
    public void testValueAndReference() {
        String ss = "woshizhu";
        modifyValue(ss);
        println(ss);
        ss = "hahaha";
        println(ss);
        modifyValue(ss);
        User user = new User("zhanghaiqiang", 28, "1");
        println(user.toString());
        mofifyReference(user);
        println(user.toString());
        Map<String, Object> map = new HashMap<>(16);
        map.put("1", 1);
        map.put("2", 2);
        println(map.toString());
        modifyMapReference(map);
        println(map.toString());


    }

    private void modifyValue(String s) {
        String sss = s.toUpperCase();
        println(s);
        println(sss);
    }

    private void mofifyReference(User user) {
        user.setName("张海强");
        user.setAge(33);
        Optional.ofNullable(user).map(User::getName);
    }

    private String modifyMapReference(Map<String, Object> map) {
        map.put("1", "zhang");
        map.put("2", "hai");
        return map.remove("1").toString();
    }

    @Test
    public void testOptional() throws IOException {
        User user = new User();
        String nameUpperCase = Optional.of(user).map(User::getName).map(String::toUpperCase).orElse("sfdsf");
        println(nameUpperCase);
        List<String> names = new ArrayList<>();
        names.add("d:\\aaa.properties");
        Optional<FileInputStream> fis =
                names.stream().filter(name -> name.length() > 0)
                        .findFirst()
                        .map(name -> {
                            FileInputStream fileInputStream = null;
                            try {
                                fileInputStream = new FileInputStream(name);
                            } catch (IOException e) {
                                System.out.println("");
                            }
                            return fileInputStream;
                        });
        if (fis.isPresent()) {
            FileInputStream fileInputStream = fis.get();
            println(fileInputStream.toString());
        }
        Stream<String> lines = Stream.of("zhang hai qiang shi zhu", "ma yun shi gou", "lei jun shi hou");
        lines.flatMap(line -> Stream.of(line.split(" "))).forEach(System.out::println);
    }

    @Test
    public void logTest() {
        logger.info("nishipigme ,nishi dogme");
        log.info("nishimoguime");
        Map<String, String> map = new TreeMap<>(Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER));
        Integer integer = Integer.valueOf(2);
        integer.intValue();
        log.info(Instant.now().toString());
        log.info(Instant.now().toEpochMilli());
        log.info(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));

    }

    @Test
    public void testToString() {
        Teacher teacher = new Teacher();
        println(teacher);
        User user = new User();
        println(user);

        teacher.xixixi();
        println(teacher.hashCode());
        Student student = new Student();
        println(student.hashCode());
        User user1 = new Teacher();
        println(user1.getClass().getName());


    }


}
